﻿using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using System.Web;
using System.Windows.Forms;


/// <summary>
/// Triple Data Encryption Standard algorithms implementations
/// </summary>
/// <Author>Yao</Author>
/// <Date>2005/4/20</Date>
namespace Loli.Library.Util
{
    public class CryptionData
    {

        /*       默认的加密模式就是DESede/CBC/PKCS5Padding
       对加密键的长度要求是24byte长，不能随意指定。
       初始化向量的长度也是8byte长，不能随意指定，
         * */

        // The length of Encryptionstring should be 24 byte and not be a weak key
        private string EncryptionString;

        // The length of initialization vector should be 8 byte
        private static Byte[] EncryptionIV = Encoding.Default.GetBytes("abcdefgh");

        /// <summary>
        /// Constructor
        /// </summary>
        public CryptionData()
        {
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="EncryptionString">SecureKey</param>
        public CryptionData(string EncryptionString)
        {
            this.EncryptionString = EncryptionString;
        }

        /// <summary>
        /// Encryption method for byte array
        /// </summary>
        /// <param name="SourceData">source data</param>
        /// <returns>byte array</returns>
        public byte[] EncryptionByteData(byte[] SourceData)
        {
            byte[] returnData = null;
            try
            {
                // Create TripleDESCryptoServiceProvider object
                TripleDESCryptoServiceProvider desProvider = new TripleDESCryptoServiceProvider();

                // Set SecureKey and IV of desProvider
                byte[] byteKey = Encoding.Default.GetBytes(EncryptionString);
                desProvider.Key = byteKey;
                desProvider.IV = EncryptionIV;

                // A MemoryStream object
                MemoryStream ms = new MemoryStream();

                // Create Encryptor
                ICryptoTransform encrypto = desProvider.CreateEncryptor();

                // Create CryptoStream object
                CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);

                // Encrypt SourceData
                cs.Write(SourceData, 0, SourceData.Length);
                cs.FlushFinalBlock();

                // Get Encryption result
                returnData = ms.ToArray();
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return returnData;

        }

        /// <summary>
        /// Decryption method for byte array
        /// </summary>
        /// <param name="SourceData">source data</param>
        /// <returns>byte array</returns>
        public byte[] DecryptionByteData(byte[] SourceData)
        {
            byte[] returnData = null;
            try
            {
                // Create TripleDESCryptoServiceProvider object
                TripleDESCryptoServiceProvider desProvider = new TripleDESCryptoServiceProvider();

                // Set SecureKey and IV of desProvider
                byte[] byteKey = Encoding.Default.GetBytes(EncryptionString);
                desProvider.Key = byteKey;
                desProvider.IV = EncryptionIV;

                // A MemoryStream object
                MemoryStream ms = new MemoryStream();

                // Create Decryptor
                ICryptoTransform encrypto = desProvider.CreateDecryptor();

                // Create CryptoStream object
                CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);

                // Decrypt SourceData
                cs.Write(SourceData, 0, SourceData.Length);
                cs.FlushFinalBlock();

                // Get Decryption result
                returnData = ms.ToArray();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return returnData;

        }

        /// <summary>
        /// Encryption method for string
        /// </summary>
        /// <param name="SourceData">source data</param>
        /// <returns>string</returns>
        public string EncryptionStringData(string SourceData)
        {
            try
            {
                // Convert source data from string to byte array
                byte[] SourData = Encoding.Default.GetBytes(SourceData);

                // Encrypt byte array
                byte[] retData = EncryptionByteData(SourData);

                // Convert encryption result from byte array to Base64String
                return Convert.ToBase64String(retData, 0, retData.Length);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Decryption method for string
        /// </summary>
        /// <param name="SourceData">source data</param>
        /// <returns>string</returns>
        public string DecryptionStringdata(string SourceData)
        {
            try
            {
                // Convert source data from Base64String to byte array
                byte[] SourData = Convert.FromBase64String(SourceData);

                // Decrypt byte array
                byte[] retData = DecryptionByteData(SourData);

                // Convert Decryption result from byte array to string
                return Encoding.Default.GetString(retData, 0, retData.Length);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}